从 UWP 迁移到 WinUI 3 的应用通知 您所在的位置:网站首页 uwp开发 azure通知 从 UWP 迁移到 WinUI 3 的应用通知

从 UWP 迁移到 WinUI 3 的应用通知

2023-07-13 16:49| 来源: 网络整理| 查看: 265

从 UWP 迁移到 WinUI 3 的应用通知 项目 06/02/2023

将应用通知代码从 UWP 迁移到 WinUI 3 时,唯一的区别在于处理通知的激活。 发送和管理应用通知完全相同。

注意

术语“toast 通知”将替换为“应用通知”。 这些术语都指 Windows 的相同功能,但随着时间的推移,我们将逐步淘汰文档中的“Toast 通知”的使用。

注意

一些信息与预发行产品相关,相应产品在商业发行之前可能会进行重大修改。 对于此处提供的信息,Microsoft 不作任何明示或暗示的担保。

激活差异 Windows 应用 SDK Windows 社区工具包 类别 UWP WinUI 3 前台激活入口点 OnActivated 调用 中的 App.xaml.cs 方法 OnLaunched 调用 中的 App.xaml.cs 方法。 后台激活入口点 作为后台任务单独处理 与前台激活相同。 OnLaunched 调用 中的 App.xaml.cs 方法。 使用 GetActivatedEventArgs 确定应用是应完全启动还是仅处理任务并退出。 窗口激活 前台激活时,窗口会自动进入前台 如果需要,必须将窗口带到前台 类别 UWP WinUI 3 前台激活入口点 OnActivated 调用 中的 App.xaml.cs 方法 订阅 ToastNotificationManagerCompat.OnActivated C++) 的事件 (或 COM 类 后台激活入口点 作为后台任务单独处理 通过 C++) 的同一 ToastNotificationManagerCompat.OnActivated 事件 (或 COM 类到达 窗口激活 前台激活时,窗口会自动进入前台 如果需要,必须将窗口带到前台 C# 应用的迁移 步骤 1:安装 NuGet 库 Windows 应用 SDK Windows 社区工具包

对于 WinUI 3 应用,可以使用 AppNotificationManager 类处理通知激活。 此类由 Microsoft.WindowsAppSDK Nuget 包提供,默认情况下包含在 WinUI 3 Visual Studio 项目模板中。

在 Visual Studio 解决方案中,右键单击项目,单击“管理 NuGet 包...”,然后搜索并安装 Microsoft.Toolkit.Uwp.NotificationsNuGet 包 7.0 或更高版本。

此包添加 ToastNotificationManagerCompat API。

步骤 2:更新清单

在 Package.appxmanifest 中,添加:

xmlns:com 声明 xmlns:desktop 声明 在 IgnorableNamespaces 属性中,添加 com 和 desktop windows.toastNotificationActivation 的 desktop:Extension,用于声明 toast 激活器 CLSID(使用你选择的新 GUID)。 仅限 MSIX:使用步骤 4 中 GUID 的 COM 激活器的 com:Extension。 务必包括 Arguments="----AppNotificationActivated:",以便了解是从通知启动 Windows 应用 SDK Windows 社区工具包 ... ... ... ... 步骤 3:处理激活 Windows 应用 SDK Windows 社区工具包

在应用的启动代码 (通常为 App.xaml.cs) 中,使用以下步骤更新代码:

在 OnLaunched 中,获取 AppNotificationManager 类的默认实例。 注册 AppNotificationManager.NotificationInvoked 事件。 调用 Microsoft.Windows.AppNotifications.AppNotificationManager.Register 注册应用以接收通知事件。 请务必在注册 NotificationInvoked 处理程序后调用此方法。 将窗口启动/激活代码重构为专用 LaunchAndBringToForegroundIfNeeded 帮助程序方法,以便可以从多个位置调用它。 创建 HandleNotification 帮助程序方法,以便可以从多个位置调用它。 调用 AppInstance.GetActivatedEventArgs 并检查返回对象的 AppActivationArguments.Kind 属性的值 ExtendedActivationKind.AppNotification。 如果激活类型不是 AppNotification ,则调用 LaunchAndBringToForegroundIfNeeded 帮助程序方法。 如果激活类型为 AppNotification ,请将 AppActivationArguments.Data 属性转换为 AppNotificationActivatedEventArgs ,并将其传递给 HandleNotification 帮助程序方法。 在 ApplicationManager.NotificationInvoked 处理程序中 HandleNotification ,调用帮助程序方法。 HandleNotification在帮助程序方法中,在执行任何与 UI 相关的代码(例如显示窗口或更新 UI)之前,请务必调度到应用或窗口调度程序 将 处理应用通知激活的旧 UWP OnActivated 代码迁移到新的 HandleNotification 帮助程序方法。 迁移的 App.xaml.cs protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args) { m_window = new MainWindow(); // To ensure all Notification handling happens in this process instance, register for // NotificationInvoked before calling Register(). Without this a new process will // be launched to handle the notification. AppNotificationManager notificationManager = AppNotificationManager.Default; notificationManager.NotificationInvoked += NotificationManager_NotificationInvoked; notificationManager.Register(); var activatedArgs = Microsoft.Windows.AppLifecycle.AppInstance.GetCurrent().GetActivatedEventArgs(); var activationKind = activatedArgs.Kind; if (activationKind != ExtendedActivationKind.AppNotification) { LaunchAndBringToForegroundIfNeeded(); } else { HandleNotification((AppNotificationActivatedEventArgs)activatedArgs.Data); } } private void LaunchAndBringToForegroundIfNeeded() { if (m_window == null) { m_window = new MainWindow(); m_window.Activate(); // Additionally we show using our helper, since if activated via a app notification, it doesn't // activate the window correctly WindowHelper.ShowWindow(m_window); } else { WindowHelper.ShowWindow(m_window); } } private void NotificationManager_NotificationInvoked(AppNotificationManager sender, AppNotificationActivatedEventArgs args) { HandleNotification(args); } private void HandleNotification(AppNotificationActivatedEventArgs args) { // Use the dispatcher from the window if present, otherwise the app dispatcher var dispatcherQueue = m_window?.DispatcherQueue ?? DispatcherQueue.GetForCurrentThread(); dispatcherQueue.TryEnqueue(async delegate { switch (args.Arguments["action"]) { // Send a background message case "sendMessage": string message = args.UserInput["textBox"].ToString(); // TODO: Send it // If the UI app isn't open if (m_window == null) { // Close since we're done Process.GetCurrentProcess().Kill(); } break; // View a message case "viewMessage": // Launch/bring window to foreground LaunchAndBringToForegroundIfNeeded(); // TODO: Open the message break; } }); } private static class WindowHelper { [DllImport("user32.dll")] private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool SetForegroundWindow(IntPtr hWnd); public static void ShowWindow(Window window) { // Bring the window to the foreground... first get the window handle... var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(window); // Restore window if minimized... requires DLL import above ShowWindow(hwnd, 0x00000009); // And call SetForegroundWindow... requires DLL import above SetForegroundWindow(hwnd); } }

在应用的启动代码 (通常为 App.xaml.cs) ,使用以下步骤更新代码:

定义和获取应用级别 DispatcherQueue 注册 ToastNotificationManagerCompat.OnActivated 事件 将窗口启动/激活代码重构为专用 LaunchAndBringToForegroundIfNeeded 方法,以便可以从多个位置调用它 如果 ToastNotificationManagerCompat.WasCurrentProcessToastActivated() 返回 true (该方法为 true,则避免启动窗口,下一步将调用事件 OnActivated ,可以选择在事件回调) 显示窗口。 ToastNotificationManagerCompat.OnActivated在 中,在执行任何与 UI 相关的代码(例如显示窗口或更新 UI)之前,请务必调度到应用或窗口调度程序 将 处理 Toast 激活的旧 UWP OnActivated 代码迁移到新的 ToastNotificationManagerCompat.OnActivated 事件处理程序,并将任何后台任务 Toast 激活代码迁移到新的 ToastNotificationManagerCompat.OnActivated 事件处理程序。 迁移的 App.xaml.cs public static DispatcherQueue DispatcherQueue { get; private set; } protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args) { // Get the app-level dispatcher DispatcherQueue = global::Microsoft.UI.Dispatching.DispatcherQueue.GetForCurrentThread(); // Register for toast activation. Requires Microsoft.Toolkit.Uwp.Notifications NuGet package version 7.0 or greater ToastNotificationManagerCompat.OnActivated += ToastNotificationManagerCompat_OnActivated; // If we weren't launched by an app, launch our window like normal. // Otherwise if launched by a toast, our OnActivated callback will be triggered if (!ToastNotificationManagerCompat.WasCurrentProcessToastActivated()) { LaunchAndBringToForegroundIfNeeded(); } } private void LaunchAndBringToForegroundIfNeeded() { if (m_window == null) { m_window = new MainWindow(); m_window.Activate(); // Additionally we show using our helper, since if activated via a toast, it doesn't // activate the window correctly WindowHelper.ShowWindow(m_window); } else { WindowHelper.ShowWindow(m_window); } } private void ToastNotificationManagerCompat_OnActivated(ToastNotificationActivatedEventArgsCompat e) { // Use the dispatcher from the window if present, otherwise the app dispatcher var dispatcherQueue = m_window?.DispatcherQueue ?? App.DispatcherQueue; dispatcherQueue.TryEnqueue(delegate { var args = ToastArguments.Parse(e.Argument); switch (args["action"]) { // Send a background message case "sendMessage": string message = e.UserInput["textBox"].ToString(); // TODO: Send it // If the UI app isn't open if (m_window == null) { // Close since we're done Process.GetCurrentProcess().Kill(); } break; // View a message case "viewMessage": // Launch/bring window to foreground LaunchAndBringToForegroundIfNeeded(); // TODO: Open the message break; } }); } private static class WindowHelper { [DllImport("user32.dll")] private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool SetForegroundWindow(IntPtr hWnd); public static void ShowWindow(Window window) { // Bring the window to the foreground... first get the window handle... var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(window); // Restore window if minimized... requires DLL import above ShowWindow(hwnd, 0x00000009); // And call SetForegroundWindow... requires DLL import above SetForegroundWindow(hwnd); } } 生成应用通知内容 Windows 应用 SDK Windows 社区工具包

使用 Windows 应用 SDK,你仍然可以使用原始 xml 创建应用通知内容,但也可以使用新的 AppNotificationsBuilder API 创建应用通知内容,该 API 取代了 Windows 社区工具包提供的 ToastContentBuilder 类。 通过调用 AppNotificationManager.Show 发送应用通知。 不建议混合使用 Windows 社区工具包和应用 SDK API。

using Microsoft.Windows.AppNotifications; using Microsoft.Windows.AppNotifications.Builder; ... var builder = new AppNotificationBuilder() .AddText("Send a message.") .AddTextBox("textBox") .AddButton(new AppNotificationButton("Send") .AddArgument("action", "sendMessage")); var notificationManager = AppNotificationManager.Default; notificationManager.Show(builder.BuildNotification());

你可以继续使用 Windows 社区工具包提供的 ToastContentBuilder 类来创建应用通知内容和在 WinUI 3 应用中发送通知。

using Microsoft.Toolkit.Uwp.Notifications; ... new ToastContentBuilder() .AddText("Send a message.") .AddInputTextBox("textBox") .AddButton(new ToastButton() .SetContent("Send") .AddArgument("action", "sendMessage")) .Show(); 相关主题 从 C# 应用发送本地 toast 通知 从 Win32 C++ WRL 应用发送本地 toast 通知


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有